#ifndef IR_H
#define IR_H
#include<bits/stdc++.h>
#include"def.h"
#include"symtable.h"
#include"driver.h"
struct sym;
struct node;
struct symtable;
#define OP_FUNCTION   0
#define OP_PARAM      1
#define OP_GOTO       2
#define OP_ARG        3
#define OP_CALL       4
#define OP_LABEL      5
#define OP_RETURN     6
#define OP_ASSIGN     7
#define OP_ADD        8
#define OP_MINUS      9
#define OP_MUL        10
#define OP_DIV        11
#define OP_MOD        12
#define OP_NEGATIVE   13
#define OP_NOT        14
#define OP_AND        15
#define OP_OR         16
#define OP_EQUAL      17
#define OP_NOTEQUAL   18
#define OP_GRATER     19
#define OP_LESS       20
#define OP_NOTGRATER  21
#define OP_NOTLESS    22
#define OP_ARRAY      23
#define OP_NULL       24

#define OPN_INT       0
#define OPN_FLOAT     1
#define OPN_SYM       3
#define OPN_TEMP      4
#define OPN_LABEL     5

struct codenode;
struct opn:sym{
   int		type;//0 int 1 float 2 sym 4 temp 5 label
   int		constInt;
   float 	constFloat;
   codenode**	cn;
   opn();
   ~opn(){}
   opn(int val);
   opn(float val);
   opn(codenode** val);
   opn(int type,int no);
   std::string toString();
};

struct codenode  
{           
private:
  int valid; //result valid   
  int cond; //if jump
  int lval; //lvalue?
public:
  int index;     
  int op;   //TAC代码的运算符种类  
  sym *opn1, *opn2, *result; //2个操作数和运算结果 
  codenode(){}
  ~codenode(){}
  codenode(int op);
  codenode(int op,sym *result);
  codenode(int op,sym* opn1,sym *result);
  codenode(int op,sym *opn1,sym *opn2,sym *result);
  void setValid();
  void setLval();
  codenode* setCond(sym* label);
  void display();
};  


struct IR{
  std::vector<codenode*> codes;
  static int labelno;
  static int index;
  static opn* genLabel();
  static opn* genTemp();
  IR(){}
  ~IR(){}
  void push(codenode* n);
  void display();
};


struct IRDriver:driver{
    int notFlag;
    int cond;
    int gap;
    codenode* cn;
    codenode* bakCn;
    IRDriver();
    IRDriver(driver* myDriver);
    static IRDriver* getIRDriver(driver* myDriver);
};

extern IR* oneIR;

int DEF_codenode        (driver* originDriver);
int FUNCDEF_codenode    (driver* originDriver);
int FUNCDEF_endlabel    (driver* originDriver);
int PARAM_codenode      (driver* originDriver);
int FUNC_codenode       (driver* originDriver);
int AND_codenode        (driver* originDriver);
int AND_reset           (driver* originDriver);
int OR_codenode         (driver* originDriver);
int OR_reset            (driver* originDriver);
int COND_set            (driver* originDriver);
int LOGICALOP_reset     (driver* originDriver);
int OP2_codenode        (driver* originDriver);
int OP1_codenode        (driver* originDriver);
int VAL_codenode        (driver* originDriver);
int ID_codenode         (driver* originDriver);
int WHILE_start         (driver* originDriver);
int WHILE_end           (driver* originDriver);
int BREAK_codenode      (driver* originDriver);
int CONTINUE_codenode   (driver* originDriver);
int BRANCH_codenode     (driver* originDriver);
int IF_codenode         (driver* originDriver);
int ELSE_codenode       (driver* originDriver);
int RETURN_codenode     (driver* originDriver);
int COND_codenode       (driver* originDriver);
#endif 
